#include "stdafx.h"
#include "LegicDemo.h"
#include "LegicDemoDlg.h"

#include "SetupApi.h"
#include "Util.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

	enum { IDD = IDD_ABOUTBOX };

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()



CLegicDemoDlg::CLegicDemoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CLegicDemoDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CLegicDemoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_COMBO_COM, m_ctrlPort);
	DDX_Control(pDX, IDC_EDIT_READER_TYPE, m_ctrlReaderType);
	DDX_Control(pDX, IDC_EDIT_HARDWARE_REV, m_ctrlHardwareRev);
	DDX_Control(pDX, IDC_EDIT_POWER, m_ctrlPower);
	DDX_Control(pDX, IDC_EDIT_BOOTLOADER, m_ctrlBootLoader);
	DDX_Control(pDX, IDC_EDIT_FIRMWARE, m_ctrlFirmware);
	DDX_Control(pDX, IDC_EDIT_CRYPTMODE, m_ctrlCryptMode);
	DDX_Control(pDX, IDC_BTN_READER_INFO, m_btnGetInfo);
	DDX_Control(pDX, IDC_BTN_SCAN_CARDS, m_btnScan);
	DDX_Control(pDX, IDC_BTN_CONNECT, m_btnConnect);
	DDX_Control(pDX, IDC_BTN_DISCONNECT, m_btnDisconnect);
	DDX_Control(pDX, IDC_BTN_READ, m_btnRead);
	DDX_Control(pDX, IDC_BTN_WRITE, m_btnWrite);
	DDX_Control(pDX, IDC_EDIT_STATUS, m_ctrlStatus);
	DDX_Control(pDX, IDC_LIST_CARDS, m_ctrlCards);
	DDX_Control(pDX, IDC_EDIT7, m_ctrlData);
}

BEGIN_MESSAGE_MAP(CLegicDemoDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BTN_READER_INFO, &CLegicDemoDlg::OnBnClickedBtnReaderInfo)
	ON_BN_CLICKED(IDC_BTN_READ, &CLegicDemoDlg::OnBnClickedBtnRead)
	ON_BN_CLICKED(IDC_BTN_WRITE, &CLegicDemoDlg::OnBnClickedBtnWrite)
	ON_BN_CLICKED(IDC_BTN_CONNECT, &CLegicDemoDlg::OnBnClickedBtnConnect)
	ON_BN_CLICKED(IDC_BTN_DISCONNECT, &CLegicDemoDlg::OnBnClickedBtnDisconnect)
	ON_BN_CLICKED(IDC_BTN_SCAN_CARDS, &CLegicDemoDlg::OnBnClickedBtnScanCards)
	ON_WM_CLOSE()
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_CARDS, &CLegicDemoDlg::OnLvnItemchangedListCards)
END_MESSAGE_MAP()


#define ICON_SIZE	0x10
BOOL CLegicDemoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	m_lstImage.Create(ICON_SIZE, ICON_SIZE, ILC_COLOR16 | ILC_MASK, 0x01, 0x02);

	HICON hIcon = AfxGetApp()->LoadIcon(IDI_CARD);
	m_lstImage.Add(hIcon);
	m_ctrlCards.SetImageList(&m_lstImage, LVSIL_SMALL);

	//m_clsFont.CreateFont(-16, 0,0,0,0,0,0,0,0,0,0,0,0, _T("Times New Roman"));
	//m_ctrlCards.SetFont(&m_clsFont);

	Scan();

	EnableConnect(TRUE);
	EnableReadWrite(FALSE);
	EnableGetInfoScan(FALSE);

	InsertColumn(0, _T("Card type"),		120	);
	InsertColumn(1, _T("Card id"),			80	);
	InsertColumn(2, _T("Subtype"),			150	);
	InsertColumn(3, _T("ATS"),				80	);
	InsertColumn(4, _T("Historic byte"),	120	);
	m_ctrlStatus.SetWindowText(_T("Wellcome to iDTronic - Legic demo program !"));
	m_ctrlCards.ModifyStyle(0, LVS_SHOWSELALWAYS | LVS_REPORT);
	m_ctrlCards.SetExtendedStyle( /*LVS_EX_FLATSB |*/LVS_EX_FULLROWSELECT);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CLegicDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

void CLegicDemoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CLegicDemoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CLegicDemoDlg::Scan()
{
	DWORD dwIndex		= 0x00;
	DWORD dwReaderPos	= 0x00;

	const GUID GUID_COM = {0x4D36E978, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}};
	HDEVINFO hDevHandle = SetupDiGetClassDevs(&GUID_COM, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);

	if(hDevHandle != INVALID_HANDLE_VALUE)
	{
		SP_DEVINFO_DATA stDevInfoData;
		stDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

		while(SetupDiEnumDeviceInfo(hDevHandle, dwIndex, &stDevInfoData))
		{
			SP_DRVINFO_DATA stDrvData;
			ZeroMemory(&stDrvData, sizeof(SP_DRVINFO_DATA));
			stDrvData.cbSize = sizeof(SP_DRVINFO_DATA);
			if(SetupDiBuildDriverInfoList(hDevHandle, &stDevInfoData, SPDIT_COMPATDRIVER))
			{
				TCHAR szPath[MAX_PATH];
				DWORD dwDataType = -1, dwAddress = -1, dwSize = MAX_PATH;
				CString strDevName = _T(""), strDevDesc = _T("");

				if(SetupDiGetDeviceRegistryProperty(hDevHandle, &stDevInfoData, SPDRP_FRIENDLYNAME, &dwDataType, (BYTE*)szPath, MAX_PATH, &dwSize))
				{
					strDevName = szPath;
					dwDataType = -1, dwAddress = -1, dwSize = MAX_PATH;
					ZeroMemory(szPath, MAX_PATH);
					if(SetupDiGetDeviceRegistryProperty(hDevHandle, &stDevInfoData, SPDRP_DEVICEDESC, &dwDataType, (BYTE*)szPath, MAX_PATH, &dwSize))
					{
						strDevDesc = szPath;
						strDevDesc += _T(" (COM");
						strDevName = strDevName.Mid(strDevDesc.GetLength());
						strDevName.Remove(_T(')'));
						_ttoi((LPCTSTR)strDevName);

						CString strCom = _T("");
						strCom.Format(_T("COM%d"), _ttoi((LPCTSTR)strDevName));
						m_ctrlPort.SetItemData(m_ctrlPort.AddString(strCom), _ttoi((LPCTSTR)strDevName));
					}
				}
				SetupDiDestroyDriverInfoList(hDevHandle, &stDevInfoData, SPDIT_COMPATDRIVER);
			}

			stDevInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
			dwIndex++;
		}
		SetupDiDestroyDeviceInfoList(hDevHandle);
		m_ctrlPort.SetCurSel(0);
	}
}

void CLegicDemoDlg::InsertColumn(UINT nCol, TCHAR* szData, UINT nMaxLen)
{
	if(szData != NULL)
	{
		LV_COLUMN stLvc;
		stLvc.mask		= LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
		stLvc.iSubItem	= nCol;
		stLvc.pszText	= szData;
		stLvc.cx		= nMaxLen;
		stLvc.fmt		= LVCFMT_LEFT;
		m_ctrlCards.InsertColumn(nCol, &stLvc);
		// m_ctrlData.SetColumnWidth( nCol, LVSCW_AUTOSIZE_USEHEADER);
	}
}

void CLegicDemoDlg::InsertItem(UINT nIntem, UINT nSubItem, TCHAR* szString, UINT nImage)
{
	LVITEM stLvItem;
	::ZeroMemory(&stLvItem, sizeof(LVITEM));

	stLvItem.iItem = nIntem;
	stLvItem.iSubItem = nSubItem;
	stLvItem.mask = LVIF_TEXT | LVIF_STATE;
	if(nImage != -1)
	{
		stLvItem.mask |= LVIF_IMAGE;
		stLvItem.iImage	 = nImage;
	}
	stLvItem.pszText = szString;
	stLvItem.cchTextMax = (int)_tcslen(szString) + 1;

	if(nSubItem == 0x00)
	{
		// set the default count to 1 - in item data
		//
		m_ctrlCards.InsertItem(&stLvItem);
	}

	if(nSubItem > 0x00)
		m_ctrlCards.SetItem(&stLvItem);
}

void CLegicDemoDlg::EnableReadWrite(BOOL bState)
{
	m_btnRead.EnableWindow(bState);
	m_btnWrite.EnableWindow(bState);
}

void CLegicDemoDlg::EnableGetInfoScan(BOOL bState)
{
	m_btnGetInfo.EnableWindow(bState);
	m_btnScan.EnableWindow(bState);
}

void CLegicDemoDlg::EnableConnect(BOOL bState)
{
	m_btnConnect.EnableWindow(bState);
	m_btnDisconnect.EnableWindow(!bState);
}

void CLegicDemoDlg::OnBnClickedBtnConnect()
{
	START_ERROR();
	UINT nPort = (UINT)m_ctrlPort.GetItemData(m_ctrlPort.GetCurSel());
	m_clsLegicProt.SetCom(nPort);
	EERROR eRet = m_clsLegicProt.Open();

	if(eRet == ER_OK)
	{
		EnableConnect(FALSE);
		EnableReadWrite(FALSE);
		EnableGetInfoScan(TRUE);
	}

	END_ERROR(_T("Error connect"));
}

void CLegicDemoDlg::OnBnClickedBtnReaderInfo()
{
	START_ERROR();

	BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
	EERROR eRet = m_clsLegicProt.GetIDB(0x00, &pDataRet, dwDataRet);
	if(eRet == ER_OK)
	{
		CString strData = _T("Unknown");
		if(pDataRet[0x00] == 0x01)
		{
			strData = _T("SM-4200");
		}
		m_ctrlReaderType.SetWindowText(strData);

		switch(pDataRet[0x01])
		{
			case 0x01: m_ctrlHardwareRev.SetWindowText(_T("V0.1")); break;
			case 0x02: m_ctrlHardwareRev.SetWindowText(_T("V0.2")); break;
			case 0x03: m_ctrlHardwareRev.SetWindowText(_T("V0.3")); break;
			case 0x04: m_ctrlHardwareRev.SetWindowText(_T("V0.9")); break;
			case 0x05: m_ctrlHardwareRev.SetWindowText(_T("V1.0")); break;
			default: m_ctrlHardwareRev.SetWindowText(_T("Unknown"));
		}

		switch(pDataRet[0x02])
		{
			case 0x01: m_ctrlPower.SetWindowText(_T("Standard power")); break;
			case 0x10: m_ctrlPower.SetWindowText(_T("Battery power")); break;
			default: m_ctrlPower.SetWindowText(_T("Unknown"));
		}

		strData.Format(_T("V%d.%d"), pDataRet[0x03], pDataRet[0x04]);
		m_ctrlBootLoader.SetWindowText(strData);

		strData.Format(_T("V%d.%d.%d.%d"), pDataRet[0x05], pDataRet[0x06], pDataRet[0x07], pDataRet[0x08]);
		m_ctrlFirmware.SetWindowText(strData);

		delete[] pDataRet;
	}

	pDataRet = NULL; dwDataRet = 0x00;
	if((eRet = m_clsLegicProt.GetIDB(0x1B, &pDataRet, dwDataRet)) == ER_OK)
	{
		switch(pDataRet[0x00])
		{
			case 0x00: m_ctrlCryptMode.SetWindowText(_T("No encryption")); break;
			case 0x01: m_ctrlCryptMode.SetWindowText(_T("AES 128 bit")); break;
			case 0x03: m_ctrlCryptMode.SetWindowText(_T("3DES")); break;
			case 0x04: m_ctrlCryptMode.SetWindowText(_T("AES 128 bit - Auth. only")); break;
			case 0x06: m_ctrlCryptMode.SetWindowText(_T("3DES - Auth. only")); break;
			default: ASSERT(FALSE);
		}
		delete[] pDataRet;
	}

	END_ERROR(_T("Error connect"));
}

void CLegicDemoDlg::CleanCardItems()
{
	EnableReadWrite(FALSE);
	m_ctrlCards.DeleteAllItems();
	m_ctrlData.SetData(NULL, 0x00);
	m_ctrlData.Invalidate(TRUE);
}

GENTYPE_TO_STRING tbScanType[]=
{
	{ECARD_LEGIC,			_T("Card Legic")		},
	{ECARD_ISO15693,		_T("Card Iso15693")		},
	{ECARD_ISO14443A,		_T("Card Iso14443A")	},
	{ECARD_ISO14443B,		_T("Card Iso14443B")	},
	{ECARD_INSIDESECURE,	_T("Card Inside Secure")},
	{ECARD_SONYFELICA,		_T("Card Sony Felica")	},
};

GENTYPE_TO_STRING tbCardSubtype[]=
{
	{ECARD_SUB_ULTRALIGHT_LEVEL1,		_T("Ultralight level 1")	},
	{ECARD_SUB_ULTRALIGHT_LEVEL2,		_T("Ultralight level 1")	},
	{ECARD_SUB_1K,						_T("Mifare 1K")				},
	{ECARD_SUB_4K,						_T("Mifare 4K")				},
	{ECARD_SUB_DESFIRE_LEVEL1,			_T("DES fire level 1")		},
	{ECARD_SUB_DESFIRE_LEVEL2,			_T("DES fire level 2")		},
	{ECARD_SUB_UNKNOWN,					_T("Not present")			},
};

void CLegicDemoDlg::OnBnClickedBtnScanCards()
{
	CleanCardItems();
	m_clsLegicProt.SetLeds(TRUE);
	DWORD dwTotalCards = 0x00;
	for(UINT nCount = 0x00; nCount < sizeof(tbScanType) / sizeof(GENTYPE_TO_STRING); nCount++)
	{
		START_ERROR();

		EERROR eRet = m_clsLegicProt.SetState(EIDLE);
		if(eRet == ER_OK)
		{
			BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00, dwNrCards = 0x00;
			EERROR eRet = m_clsLegicProt.GetCardsExt((ECARDTYPE)(tbScanType[nCount].eCardType), dwNrCards, &pDataRet, dwDataRet);
			if(eRet == ER_OK)
			{
				dwTotalCards += dwNrCards;
				for(DWORD dwCard = 0; dwCard < dwNrCards; dwCard++)
				{
					CARD_SAVE_INFO stCardSaveInfo;
					stCardSaveInfo.dwCardInfo = 0x00;
					PCARD_INFO pCardInfo = ((PCARD_INFO)pDataRet) + dwCard;
					stCardSaveInfo.CardInfo.bCardType		= pCardInfo->bCardType;
					stCardSaveInfo.CardInfo.bCardSubtype	= pCardInfo->bCardSubType;
					stCardSaveInfo.CardInfo.bCardPos		= (BYTE)(dwCard + 0x01);

					// m_clsLegicProt.SetBuzzer(TRUE);
					// display cards id !!!
					CString strTmp = CUtil::ByteToString(pCardInfo->pCardId, pCardInfo->bLenCardId);
					InsertItem(0, 0, tbScanType[nCount].szMsg, -1);
					InsertItem(0, 1, (TCHAR*)(LPCTSTR)strTmp, -1);
					InsertItem(0, 2, tbCardSubtype[pCardInfo->bCardSubType].szMsg, -1);

					strTmp = _T("No ATS");
					if(pCardInfo->bLenATS > 0x00)
					{
						strTmp = CUtil::ByteToString(pCardInfo->pCardATS, pCardInfo->bLenATS);
					}
					InsertItem(0, 3, (TCHAR*)(LPCTSTR)strTmp, -1);

					strTmp = _T("No Historical bytes");
					if(pCardInfo->bLenHistoricByte > 0x00)
					{
						strTmp = CUtil::ByteToString(pCardInfo->pHistoricByte, pCardInfo->bLenHistoricByte);
					}
					InsertItem(0, 4, (TCHAR*)(LPCTSTR)strTmp, -1);

					m_ctrlCards.SetItemData(0, stCardSaveInfo.dwCardInfo);
				}
				delete[] pDataRet;
			}
		}

		m_ctrlCards.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);

		CString strRet = _T("");
		strRet.Format(_T("Total cards: %d. Scan result"), dwTotalCards);
		END_ERROR(strRet);
	}
	m_clsLegicProt.SetLeds(FALSE);
} 

EERROR CLegicDemoDlg::ReadLegicCard()
{ 
	BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
	DWORD dwFileSize = 0x00;

	EERROR eRet = m_clsLegicProt.SelectFile(1, FILE_DATA_SEG, NULL, 0x00, dwFileSize);
	if(eRet == ER_OK)
	{
		BYTE pDataRead[MAX_PATH]; DWORD dwRead = 0x10;
		if((eRet = m_clsLegicProt.ReadFile(0x00, pDataRead, dwFileSize)) == ER_OK)
		{
			m_ctrlData.SetData(pDataRead, dwFileSize);
			m_ctrlData.Invalidate(TRUE);
		}
	}
	return eRet;
}

EERROR CLegicDemoDlg::ReadUltralightCard()
{ 
	BYTE pMainData[MAX_PATH];
	EERROR eRet = ER_OK; UINT nCount = 0x00;
	while((eRet == ER_OK) && (nCount != 0x04))
	{
		BYTE pData[0x05];
		pData[0x00] = 0x04;
		pData[0x01] = 0x30;
		pData[0x02] = (BYTE)nCount;
		*(WORD*)(pData + 0x03) = (WORD)CUtil::CalcCRC16(pData + 0x01, 0x02, 0x6363, 0x8408);
		/*pData[0x03] = (BYTE)(CUtil::CalcCRC16(pData + 0x01, 0x02, 0x6363, 0x8408) >> 0x08);
		pData[0x04] = (BYTE)CUtil::CalcCRC16(pData + 0x01, 0x02, 0x6363, 0x8408);*/

		BYTE* pDataRet = NULL; DWORD dwDataRet = 0x00;
		if((eRet = m_clsLegicProt.Envelope(pData, 0x05, &pDataRet, dwDataRet)) == ER_OK)
		{
			eRet = ER_INVALID_DATA;
			if(pDataRet[0x00] == 0x12)
			{ 
				memcpy_s(pMainData + nCount * 0x10, MAX_PATH, pDataRet + 0x01, 0x10);
				eRet = ER_OK;
			}
		}

		delete[] pDataRet;
		nCount++;
	}

	if(eRet == ER_OK)
	{
		m_ctrlData.SetData(pMainData, nCount * 0x10);
		m_ctrlData.Invalidate(TRUE);
	}
	return eRet;
}

void CLegicDemoDlg::OnBnClickedBtnRead()
{
	START_ERROR();

	m_clsLegicProt.SetLeds(TRUE);
	EERROR eRet = ER_NO_TAG;
	POSITION nPos = m_ctrlCards.GetFirstSelectedItemPosition();
	if(nPos != NULL)
	{
		int iItem = m_ctrlCards.GetNextSelectedItem(nPos);
		if(iItem != LB_ERR)
		{
			DWORD dwCard = (DWORD)m_ctrlCards.GetItemData(iItem);
			if(dwCard != -1)
			{
				if((eRet = m_clsLegicProt.SetState(EIDLE)) == ER_OK)
				{
					DWORD dwCards = -1, dwSize = 0x00; BYTE* pCards;
					CARD_SAVE_INFO stCardSaveInfo; stCardSaveInfo.dwCardInfo = dwCard;
					if((eRet = m_clsLegicProt.GetCardsExt((ECARDTYPE)(stCardSaveInfo.CardInfo.bCardType), dwCards, &pCards, dwSize)) == ER_OK)
					{
						BYTE bState = -1;
						m_clsLegicProt.GetState(bState);

						delete[] pCards;
						if((eRet = m_clsLegicProt.SelectCard((ECARDTYPE)(stCardSaveInfo.CardInfo.bCardType), stCardSaveInfo.CardInfo.bCardPos - 1, 0x00)) == ER_OK)
						{
							dwTime = GetTickCount();
							switch(stCardSaveInfo.CardInfo.bCardType)
							{
								case ECARD_LEGIC: eRet = ReadLegicCard(); break;
								case ECARD_ISO14443A: 
								{
									switch(stCardSaveInfo.CardInfo.bCardSubtype)
									{
										case ECARD_SUB_ULTRALIGHT_LEVEL2: eRet = ReadUltralightCard(); break;
									}
								}break;
							}
						}
					}
				}
			}
		}
	}

	m_clsLegicProt.SetLeds(FALSE);
	END_ERROR(_T("Error reading"));
}

void CLegicDemoDlg::OnBnClickedBtnWrite()
{
	START_ERROR();

	m_clsLegicProt.SetLeds(TRUE);
	EERROR eRet = ER_NO_TAG;
	POSITION nPos = m_ctrlCards.GetFirstSelectedItemPosition();
	if(nPos != NULL)
	{
		int iItem = m_ctrlCards.GetNextSelectedItem(nPos);
		if(iItem != LB_ERR)
		{
			DWORD dwCard = (DWORD)m_ctrlCards.GetItemData(iItem);
			if(dwCard != -1)
			{
				if((eRet = m_clsLegicProt.SetState(EIDLE)) == ER_OK)
				{
					DWORD dwCards = -1, dwSize = 0x00; BYTE* pCards;
					if((eRet = m_clsLegicProt.GetCards(ECARD_LEGIC, dwCards, &pCards, dwSize)) == ER_OK)
					{
						delete[] pCards;
						if((eRet = m_clsLegicProt.SelectCard(ECARD_LEGIC, dwCard - 1, 0x00)) == ER_OK)
						{
							DWORD dwFileSize = 0x00;
							if((eRet = m_clsLegicProt.SelectFile(0, FILE_DATA_SEG, NULL, 0x00, dwFileSize)) == ER_OK)
							{
								BYTE pDataRead[MAX_PATH];
								m_ctrlData.GetData(pDataRead, dwFileSize);
								eRet = m_clsLegicProt.WriteFile(0x00, pDataRead, dwFileSize);
							}
						}
					}
				}
			}
		}
	}

	m_clsLegicProt.SetLeds(FALSE);
	END_ERROR(_T("Error writing"));
}

void CLegicDemoDlg::OnBnClickedBtnDisconnect()
{
	START_ERROR();
	m_clsLegicProt.SetLeds(FALSE);
	EERROR eRet = m_clsLegicProt.Close();

	if(eRet == ER_OK)
	{
		EnableConnect(TRUE);
		EnableReadWrite(FALSE);
		EnableGetInfoScan(FALSE);
	}
	END_ERROR(_T("Error disconnect"));
}

void CLegicDemoDlg::OnClose()
{
	m_clsLegicProt.Close();

	CleanCardItems();

	CDialog::OnClose();
}

void CLegicDemoDlg::OnLvnItemchangedListCards(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
	
	BOOL bEnableRead = FALSE;
	if(pNMLV != NULL)
	{
		if(m_ctrlCards.GetItemData(pNMLV->iItem) > 0)
		{
			bEnableRead = TRUE;
		}
	}
	EnableReadWrite(bEnableRead);
	*pResult = 0;
}
